﻿namespace Yaaf.WP7.NativeAccess.IO
{
    using System;
    using System.IO;

    public abstract class FileSystemEntry
    {
        private readonly string fullName;

        public abstract bool Exists { get; }

        public abstract void Delete();

        public string FullName
        {
            get
            {
                return this.fullName;
            }
        }
        
        public string Name
        {
            get
            {
                return Path.GetFileName(FullName);
            }
        }

        public DirectoryInfo Parent
        {
            get
            {
                if (string.IsNullOrEmpty(this.FullName) || this.FullName == "\\")
                {
                    return null;
                }
                string fn = this.FullName;
                //if (FullName.EndsWith("\\"))
                //{
                //    fn = FullName.Substring(0, FullName.Length - 1);
                //}

                return new DirectoryInfo(fn.Substring(0, fn.LastIndexOf("\\")));
            }
        }

        public FileSystemEntry(string fullName)
        {
            if (fullName == null)
            {
                throw new ArgumentNullException("fullName");
            }

            if (fullName.EndsWith("\\") && fullName.Length > 1)
            {
                fullName = fullName.Substring(0, fullName.Length - 1);
            }

            this.fullName = fullName;
        }

        protected internal static FileSystemEntry GetFileSystemEntry(FileSystemEntryStruct entryStruct)
        {
            var fullName = entryStruct.Name;
            if (!entryStruct.IsFile.HasValue)
            {
                var pathInformation = PathInfo.GetPathInformation(fullName);
                switch (pathInformation)
                {
                    case PathInformation.NotExistent:
                        throw new ArgumentException("If fullname does not exist we can not create a FileSystemEntry!", "fullName");
                        break;
                    case PathInformation.File:
                        return new FileInfo(entryStruct);
                        break;
                    case PathInformation.Directory:
                        return new DirectoryInfo(fullName);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            else
            {
                if (entryStruct.IsFile.Value)
                {
                    return new FileInfo(fullName);
                }
                else
                {
                    return new DirectoryInfo(fullName);
                }
            }
           
        }

        public abstract FileSystemEntry Move(DirectoryInfo targetDir, string newName = null, bool overwrite = false);

        public abstract FileSystemEntry CopyTo(DirectoryInfo currentDir, string newName = null, bool overwrite = false);
    }
}